package dual;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Set;

import sample.Vertex;
import triangulation.Polygon;
import triangulation.Triangle;

public class DualGraph
{
	public ArrayList<DualVertex> dVertexList;

	public DualGraph(ArrayList<Triangle> triList)
	{
		dVertexList = new ArrayList<DualVertex>();
		constructDual(triList);
	}

	private void constructDual(ArrayList<Triangle> triList)
	{
		// create each dual vertex as individual nodes
		for (Triangle t : triList)
		{
			dVertexList.add(new DualVertex(t));
		}

		// check each triangle with the others to find the neighboring triangles
		for (DualVertex dv : dVertexList)
		{
			for (DualVertex dvCheck : dVertexList)
			{
				if (!dv.equals(dvCheck) && dv.hasCommonEdge(dvCheck))
				{
					dv.addChild(dvCheck);
				}
			}
		}
//
//		// print the dual graph
//		for (DualVertex dv : dVertexList)
//			System.out.println(dv);
	}

	public void draw(Graphics g)
	{

		g.setColor(Color.BLUE);
		for (DualVertex d : dVertexList)
		{
			Point centerPoint = d.getCenter();
			g.fillOval(centerPoint.x - 5, centerPoint.y - 5, 10, 10);
			g.drawString("" + d.tri.label, centerPoint.x + 10, centerPoint.y + 10);

			for (DualVertex child : d.children)
			{
				g.drawLine(d.getCenter().x, d.getCenter().y, child.getCenter().x, child.getCenter().y);
			}
		}
		g.setColor(Color.BLACK);
	}

	/**
	 * Given a list of triangles (in dual vertex form), this method constructs the simple polygon.
	 * 
	 * @param tList
	 * @return
	 */
	public static Polygon constructPolyFromDualVertices(ArrayList<DualVertex> tList)
	{
		Polygon poly = new Polygon();
		Set<Vertex> s = new HashSet<Vertex>();
		ArrayList<Vertex> vertices = new ArrayList<Vertex>();

		for (DualVertex d : tList)
		{
			ArrayList<Vertex> subvertices = d.tri.getVertices();

			for (Vertex subV : subvertices)
			{
				s.add(subV);
			}
		}

		vertices.addAll(s);

		// sort the vertices to not to disturb the orientation.
		Collections.sort(vertices, new Comparator<Vertex>()
		{
			public int compare(Vertex a, Vertex b)
			{
				return a.getIndex() - b.getIndex();
			}
		});

		poly.constructPoly(vertices);

		// poly.printAdjList();

		return poly;
	}

	/**
	 * Given a new dual vertex(use its triangle), extend the polygon by adding this one.
	 * 
	 * @param poly
	 * @param dVertex
	 * @return
	 */
	public static Polygon extendPolygon(Polygon poly, DualVertex dVertex)
	{
		Set<Vertex> s = new HashSet<Vertex>();
		ArrayList<Vertex> vertices = new ArrayList<Vertex>();

		for (Vertex v : dVertex.tri.getVertices())
		{
			s.add(v);
		}
		for (Vertex v : poly.getVertices())
		{
			s.add(v);
		}
		
		vertices.addAll(s);

		// sort the vertices to not to disturb the orientation.
		Collections.sort(vertices, new Comparator<Vertex>()
		{
			public int compare(Vertex a, Vertex b)
			{
				return a.getIndex() - b.getIndex();
			}
		});
		
		System.out.println("extend edilen graph:" + vertices);
		Polygon p = new Polygon();
		p.constructPoly(vertices);
		p.generateDcelOfPolygon();
		p.hasFixedGuard=poly.hasFixedGuard;
		p.guard = poly.guard;
		return p;
	}

}
